package com.momoc.multi.chat.room.core.session;


import com.google.protobuf.MessageLiteOrBuilder;
import com.momoc.multi.chat.room.common.config.MachineConfig;
import com.momoc.multi.chat.room.common.dto.AuroraQueueMessageDTO;
import com.momoc.multi.chat.room.common.dto.UserOnlineCacheDTO;
import com.momoc.multi.chat.room.common.model.channel.ChannelMemberPojo;
import com.momoc.multi.chat.room.common.proto.ChannelMessage;
import com.momoc.multi.chat.room.common.utils.AssertUtil;
import com.momoc.netty.frame.ProtobufUtils;
import com.momoc.multi.chat.room.common.utils.RedisUtils;
import com.momoc.multi.chat.room.common.vo.AppUserInfo;
import com.momoc.multi.chat.room.common.vo.UserChannelInfoVO;
import com.momoc.multi.chat.room.core.event.user.UserLoginEvent;
import com.momoc.multi.chat.room.core.producer.ProducerDispatchMessageCenter;
import com.momoc.multi.chat.room.core.service.IChannelService;
import com.momoc.netty.frame.event.annotation.WebsocketEvent;
import com.momoc.netty.frame.session.vo.UserSessionInfo;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;

/**
 * @author momoc
 * @version 1.0
 * @className ChannelManagerContext
 * @description
 * @date 2023/9/1 16:28
 */
@RequiredArgsConstructor
@WebsocketEvent
public class ChannelManagerContext {



    final ProducerDispatchMessageCenter dispatchMessageCenter;
    final IChannelService channelService;
    final RedisUtils redisUtils;
    final SessionManagerContext sessionManagerContext;


    /**
     * 用户上线时，要在频道
     * @param userLoginEvent
     */
    @EventListener(classes = UserLoginEvent.class)
    public void onlineMember(UserLoginEvent userLoginEvent){
        AppUserInfo appUserInfo = userLoginEvent.getAppUserInfo();

        List<ChannelMemberPojo> channelMemberPojoList = channelService.findUserChannel(appUserInfo.getId());

        AuroraQueueMessageDTO auroraQueueMessageDTO = new AuroraQueueMessageDTO();

        ArrayList<UserOnlineCacheDTO> userOnlineCacheDTOS = new ArrayList<>();

        auroraQueueMessageDTO.setUserList(userOnlineCacheDTOS);
        for (ChannelMemberPojo channelMemberPojo : channelMemberPojoList) {
            Long channelId = channelMemberPojo.getChannelId();
            ChannelMessage.UserOnlineStatusNotice_1007.Builder builder = ChannelMessage.UserOnlineStatusNotice_1007.newBuilder();
            builder.setChannelId(channelId)
                    .setUserid(appUserInfo.getId())
                    .setOnline(true);
            ChannelMessage.UserOnlineStatusNotice_1007 build = builder.build();
            sendMsgToChannel(channelId, build);
        }
    }

    /**
     * 移除在线人员
     * @param userSessionInfo
     */
    public  void close(UserSessionInfo<AppUserInfo> userSessionInfo)  {
        AppUserInfo appUserInfo = userSessionInfo.getAppUserInfo();
        Long userid = appUserInfo.getId();
        List<ChannelMemberPojo> channelMemberPojoList = channelService.findUserChannel(appUserInfo.getId());

        AuroraQueueMessageDTO auroraQueueMessageDTO = new AuroraQueueMessageDTO();

        ArrayList<UserOnlineCacheDTO> userOnlineCacheDTOS = new ArrayList<>();
        auroraQueueMessageDTO.setUserList(userOnlineCacheDTOS);
        for (ChannelMemberPojo channelMemberPojo : channelMemberPojoList) {
            Long channelId = channelMemberPojo.getChannelId();
            ChannelMessage.UserOnlineStatusNotice_1007.Builder builder = ChannelMessage.UserOnlineStatusNotice_1007.newBuilder();
            builder.setChannelId(channelId)
                    .setUserid(userid)
                    .setOnline(false);
            ChannelMessage.UserOnlineStatusNotice_1007 build = builder.build();
            sendMsgToChannel(channelId, build);
        }
    }


    /**
     * 给频道的人发送消息
     * @param channelId
     * @param message
     */
    public void sendMsgToChannel(Long channelId, MessageLiteOrBuilder message)  {
        List<UserChannelInfoVO> channelAllUser = channelService.getChannelAllUser(channelId);

        ByteBuf byteBuf = ProtobufUtils.encodeResponseMessage(message);
        AuroraQueueMessageDTO auroraQueueMessageDTO = new AuroraQueueMessageDTO();
        byte[] byteArray = new byte[byteBuf.readableBytes()]; // 创建一个等长度的 byte 数组
        byteBuf.getBytes(0, byteArray); //将 ByteBuf 转换为对应的 byte 数组
        auroraQueueMessageDTO.setMessageBody(byteArray);

        ArrayList<UserOnlineCacheDTO> userOnlineCacheDTOS = new ArrayList<>();
        auroraQueueMessageDTO.setUserList(userOnlineCacheDTOS);
        for (UserChannelInfoVO userChannelInfoVO : channelAllUser) {

            String tokenWs = sessionManagerContext.isUserOnline(userChannelInfoVO.getUserid());
            /**
             * 用户不在线不需要发送
             */
            if (AssertUtil.isEmpty(tokenWs)){
                continue;
            }

            UserOnlineCacheDTO userOnlineCacheDTO = new UserOnlineCacheDTO();
            userOnlineCacheDTO.setMachineId(MachineConfig.getMachineId());
            userOnlineCacheDTO.setUserId(String.valueOf(userChannelInfoVO.getUserid()));

            userOnlineCacheDTO.setTokenWs(tokenWs);

            userOnlineCacheDTOS.add(userOnlineCacheDTO);
        }
        if (!userOnlineCacheDTOS.isEmpty()){
            dispatchMessageCenter.sendMessageToQueue(auroraQueueMessageDTO);
        }
    }

}
